package com.soyoung.exception;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.soyoung.enums.Enums;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * exception common class
 */
public class DefaultExceptionHandler {

    private static Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionHandler.class);

    @ExceptionHandler
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ex.printStackTrace();
        ModelAndView mv = new ModelAndView();
        /*使用FastJson提供的FastJsonJsonView视图返回,不需要捕获异常*/
        FastJsonJsonView view = new FastJsonJsonView();
        Map<String, Object> attributes=handleDeviceNetworkException(ex);
        view.setAttributesMap(attributes);
        mv.setView(view);
        LOGGER.debug("异常" + ex.getMessage(), ex);
        return mv;
    }

    private Map<String, Object> handleDeviceNetworkException(Exception ex){
        ex.printStackTrace();
        if (ex instanceof TypeMismatchException) {
            return convertMap(Enums.ResStatus.PARAM_ERROR.getCode(), Enums.ResStatus.PARAM_ERROR.getDesc());
        } else if (ex instanceof HttpMessageNotReadableException) {
            return convertMap(Enums.ResStatus.INVALID_REQUEST.getCode(),Enums.ResStatus.INVALID_REQUEST.getDesc());
        } else if (ex instanceof MissingServletRequestParameterException) {
            return convertMap(Enums.ResStatus.PARAM_NULL.getCode(),Enums.ResStatus.PARAM_NULL.getDesc());
        } else if (ex instanceof BindException) {
            return convertMap(Enums.ResStatus.PARAM_ERROR.getCode(),Enums.ResStatus.PARAM_ERROR.getDesc());
        } else if (ex instanceof MethodArgumentNotValidException) {
            return convertMap(Enums.ResStatus.PARAM_ERROR.getCode(),Enums.ResStatus.PARAM_ERROR.getDesc());
        }else if(ex instanceof MaxUploadSizeExceededException){
            return convertMap(Enums.ResStatus.FILE_OUTOF_MAX_SIZE_ERROR.getCode(), Enums.ResStatus.FILE_OUTOF_MAX_SIZE_ERROR.getDesc());
        } else if (ex instanceof HttpMediaTypeNotSupportedException) {
            return convertMap(Enums.ResStatus.INVALID_REQUEST.getCode(), Enums.ResStatus.INVALID_REQUEST.getDesc());
        } else if(ex instanceof MultipartException){
            return convertMap(Enums.ResStatus.INVALID_REQUEST.getCode(),Enums.ResStatus.INVALID_REQUEST.getDesc());
        } else if(ex instanceof IllegalArgumentException){
            return convertMap(Enums.ResStatus.PARAM_ERROR.getCode(),Enums.ResStatus.PARAM_ERROR.getDesc());
        } else if(ex instanceof JSONException){
            return convertMap(Enums.ResStatus.DATA_FORMAT_ERROR.getCode(),Enums.ResStatus.DATA_FORMAT_ERROR.getDesc());
        }
        return convertMap(Enums.ResStatus.SYSTEM_ERROR.getCode(),Enums.ResStatus.SYSTEM_ERROR.getDesc());
    }

    public Map<String, Object> convertMap(String code,String error){
        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put("code", code);
        attributes.put("desc", error);
        return attributes;
    }
}
